@page "/todo"
@using System.Globalization
@using Templates.TodoApp.Services
@inherits ComputedStateComponent<Todo[]>
@inject Session Session
@inject ITodos Todos
@inject TodoUI TodoUI
@inject UICommander UICommander
@inject ILogger<TodoPage> Log

@{
    var c = State.Computed;
    Log.LogInformation(
        "Rendering, Computed.Version = {Version}, IsConsistent = {IsConsistent}",
        c.Version, c.IsConsistent());
    var error = c.Error;
    var todos = c.ValueOrDefault ?? Array.Empty<Todo>(); // ValueOrDefault returns default if there is an Error
}

<h1>Todo List</h1>

<TextConnectionStatus />
<StateOfStateBadge State="@State" />
<Div Margin="Margin.Is1.OnY">
    Updated: <b><MomentsAgoBadge Value="LastStateUpdateTime" /></b>
</Div>
<Div Margin="Margin.Is1.OnY">
    Current culture: <b>@(CultureInfo.CurrentUICulture.Name)</b> @@ @LastStateUpdateTime.ToString("D")
</Div>
<Div Margin="Margin.Is1.OnY">
    Call:
    <Button Color="Color.Danger" Size="Size.Small" Clicked="_ => StateHasChanged()">StateHasChanged()</Button>
    <Button Color="Color.Danger" Size="Size.Small" Clicked="_ => State.Invalidate()">State.Invalidate()</Button>
    <Button Color="Color.Danger" Size="Size.Small" Clicked="_ => State.Recompute()">State.Recompute()</Button>
</Div>

<AuthorizeView>
    <NotAuthorized>
        <SignInDropdown Why="to use this page" />
    </NotAuthorized>
    <Authorized>
        <WhenException Exception="error" />
        <Row>
            <Column ColumnSize="ColumnSize.Is6.OnDesktop.Is12.OnTablet">
                <Paragraph>
                    <TodoSummaryBadge/>
                </Paragraph>

                @foreach (var todo in todos) {
                    <TodoItemView @key="@todo.Id" Value="@todo" />
                }

                @if (HasMore) {
                    <Button Clicked="_ => LoadMore()" Color="Color.Primary" Margin="Margin.Is3.OnY">
                        Load @PageSize more <Blazorise.Icon Name="FontAwesomeIcons.AngleDoubleDown"/>
                    </Button>
                }

                <Form @onsubmit="Create" Margin="Margin.Is3.OnY">
                    <Addons>
                        <Addon AddonType="AddonType.Start">
                            <Button Type="@ButtonType.Submit" Color="Color.Primary">
                                <Blazorise.Icon Name="@FontAwesomeIcons.PlusSquare"/>
                            </Button>
                        </Addon>
                        <input @bind="NewTodoTitle" @bind:event="onchange" class="form-control"/>
                    </Addons>
                </Form>
            </Column>
        </Row>
    </Authorized>
</AuthorizeView>

@code {
    private int PageSize { get; set; } = 5;
    private bool HasMore { get; set; }
    private string NewTodoTitle { get; set; } = "";
    private DateTime LastStateUpdateTime { get; set; } = DateTime.UtcNow;
    // AuthState property below seemingly does nothing, right?
    // But try to comment out this line & sign-in + sign-out.
    // See the error badge stays there for a while now?
    // Check your explanation on our Discord: https://discord.gg/EKEwv6d
    [CascadingParameter] protected Task<AuthState> AuthState { get; set; } = null!;

    protected override async Task OnInitializedAsync()
    {
        var objectId = await Todos.GetTestObjectId();
        Log.LogInformation("Test ObjectId: {ObjectId}", objectId);
        var stream = await Todos.GetTestStream();
        Log.LogInformation("Test stream: {Stream}", stream);
        var itemCount = await stream.CountAsync();
        Log.LogInformation("Test stream item count: {Count}", itemCount);
    }

    protected override async Task<Todo[]> ComputeState(CancellationToken cancellationToken)
    {
        _ = State.ValueOrDefault; // To trigger NullReferenceException when State setup is off
        var items = await TodoUI.List(PageSize + 1, cancellationToken);
        HasMore = items.Length > PageSize;
        if (HasMore)
            items = items[..PageSize];
        LastStateUpdateTime = DateTime.UtcNow;
        return items;
    }

    private void LoadMore()
    {
        PageSize *= 2;
        _ = State.Recompute();
    }

    private void Create()
    {
        var todo = new Todo("", NewTodoTitle);
        NewTodoTitle = "";
        _ = UICommander.Run(new Todos_AddOrUpdate(Session, todo));
    }
}
